using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Serialization;
using Awaiter;
using Nsb.Classes;

namespace Yoshi.Classes
{
    [IgnoreNamespace]
    public class FileManager
    {
        [AlternateSignature]
        public static extern void UpdateFileAw(Await awp, string parKey, string rowKey, Action<object> fnModify);

        [AlternateSignature]
        public static extern void UpdateFileAw(Await awp, string parKey, string rowKey, Action<object, object[]> fnModify);

        [AlternateSignature]
        public static extern void UpdateFileAw(Await awp, string parKey, string rowKey, Action<object> fnModify, Action fnComplete);

        public static void UpdateFileAw(Await awp, string parKey, string rowKey, Action<object, object[]> fnModify, Action fnComplete)
        {
            fnComplete = fnComplete ?? Helpers.NoOp;
            new Await()
                .AddAw(FileBlobBase.RetrieveBlobStringAw, parKey, rowKey)
                .HandleDl(Exceptions.BlobLoadError,
                          delegate(Await aw)
                          {
                              Inform.Error("Could not load {0}", Uri.Join(parKey, rowKey));
                              aw.Result = null;
                              aw.Done();
                          })
                .AddDl(
                    delegate(Await aw)
                    {
                        object content = aw.Result != null ? Json.Parse((string)aw.Result) : null;
                        object[] passed = (object[])new List<object>(content);
                        fnModify(content, passed);
#if DEBUG
                        string output = Rx.PrettyJson(passed[0]);
#else
                        string output = Json.Stringify(content);
#endif
                        Uri.BumpVersion();
                        new Await()
                            .AddAw(FileBlobBase.StoreBlobStringAw, new Dictionary("partitionKey", parKey, "rowKey", rowKey, "content", output, "backup", true))
                            .AddFn(fnComplete)
                            .Commit(aw);
                    })
                .Commit(awp);
        }
    }
}
